<template>
  <div class="universal-table-container" :style="{ width: tableWidth }">
    <!-- 搜索区域 -->
    <div class="search-area">
      <el-form :model="searchForm" ref="searchForm" inline>
        <!-- 关键字搜索 -->
        <el-form-item prop="keyword" v-if="showKeywordSearch">
          <el-input v-model="searchForm.keyword" placeholder="请输入关键字" clearable
            @keyup.enter.native="handleSearch"></el-input>
        </el-form-item>

        <!-- 日期范围 -->
        <el-form-item prop="dateRange" v-if="showDateRange">
          <el-date-picker v-model="searchForm.dateRange" type="daterange" range-separator="至" start-placeholder="开始日期"
            end-placeholder="结束日期" value-format="yyyy-MM-dd"></el-date-picker>
        </el-form-item>

        <!-- 搜索区域插槽 -->
        <slot name="searchExtend"></slot>
        <slot name="searchExtend2"></slot>

        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
          <span class="button-fix"></span>
          <el-button v-if="showExport && hasPermission(`${permissionPrefix}:export`)"
            @click="handleExport">{{ customExport ? '导出CSV' : '导出Excel' }}</el-button>

          <el-button type="primary" @click="handleAdd"
            v-if="showAdd && hasPermission(`${permissionPrefix}:add`)">新增</el-button>

        </el-form-item>
      </el-form>




    </div>

    <!-- 表格区域 -->
    <div class="table-area">
      <el-table :data="tableData" border stripe v-loading="tableLoading" :header-cell-style="{ background: '#f5f7fa' }"
        height="calc(100vh - 315px)" @selection-change="handleSelectionChange">
        <!-- 多选列 -->
        <el-table-column v-if="showSelection" type="selection" width="55" align="center"></el-table-column>

        <!-- 序号列 -->
        <el-table-column v-if="showIndex" label="序号" type="index" width="60" align="center"></el-table-column>

        <!-- 动态列 -->
        <template v-for="column in columns">
          <!-- 状态列特殊处理 -->
          <el-table-column v-if="column.prop === 'status'" :key="column.prop" :label="column.label"
            :width="column.width" :align="column.align || 'center'">
            <template slot-scope="scope">
              <el-switch 
                v-model="scope.row.status" 
                :active-value="1" 
                :inactive-value="0"
                :disabled="statusChangingRows.has(scope.row.id)"
                @change="handleStatusChange(scope.row)" 
                v-if="hasPermission(`${permissionPrefix}:status`)">
              </el-switch>
              <span v-else>{{ scope.row.status ? '启用' : '禁用' }}</span>
            </template>
          </el-table-column>

          <el-table-column v-else-if="column.prop === 'avatar'" :key="column.prop" :label="column.label"
            :width="column.width" :align="column.align || 'center'">
            <template slot-scope="scope">
              <el-avatar :size="50" :src="$imageFull(scope.row.avatar)"></el-avatar>
            </template>
          </el-table-column>

          <!-- 普通列 -->
          <el-table-column v-else :key="column.prop" :prop="column.prop" :label="column.label" :width="column.width"
            :align="column.align || 'center'">
            <!-- 自定义列内容插槽 -->
            <template slot-scope="scope">
              <!-- 优先级1：渲染自定义插槽内容 -->
              <slot v-if="column.slot" :name="column.slot" :row="scope.row"></slot>
              <!-- 优先级2：渲染标签内容（如果配置了tag） -->
              <el-tag v-else-if="column.tag" :type="getTagType(scope.row[column.prop], column)">
                {{ displayEmpty(getTagText(scope.row[column.prop], column)) }}
              </el-tag>
              <!-- 默认渲染：普通文本或格式化内容 -->
              <span v-else>
                {{ column.formatter ? (column.formatter(scope.row) || '-') : (scope.row[column.prop] || '-') }}
              </span>
            </template>




          </el-table-column>
        </template>

        <!-- 操作列 -->
        <el-table-column label="操作" :width="operationWidth" align="center" fixed="right" v-if="showOperation">
          <template slot-scope="scope">
            <!-- 编辑按钮 -->
            <el-button size="mini" type="primary" @click="handleEdit(scope.row)"
              v-if="hasPermission(`${permissionPrefix}:edit`) && bt1Name">{{ bt1Name }}</el-button>

            <!-- 删除按钮 -->
            <el-button size="mini" type="danger" @click="handleDelete(scope.row)"
              v-if="hasPermission(`${permissionPrefix}:delete`) && bt2Name">{{ bt2Name}}</el-button>

            <!-- 操作栏扩展插槽 -->
            <slot name="operationExtend" :row="scope.row"></slot>

            <!-- 操作栏扩展插槽 -->
            <slot name="operationExtend2" :row="scope.row"></slot>

          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- 分页区域 -->
    <div class="pagination-area" v-if="showPagination">
      <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
        :current-page="pagination.currentPage" :page-sizes="[10, 20, 30, 500, 1000]" :page-size="pagination.pageSize"
        layout="total, sizes, prev, pager, next, jumper" :total="pagination.total"></el-pagination>
    </div>
  </div>
</template>

<script>
  import {
    exportJsonToExcel
  } from "@/utils/export2Excel";
  import {
    mapGetters
  } from "vuex";
  export default {

    props: {
      tableWidth: { // 新增宽度属性
        type: String,
        default: '100%'
      },
      // 表格列配置
      columns: {
        type: Array,
        required: true,
        default: () => [],
      },
      // 获取数据的函数
      fetchData: {
        type: Function,
        required: true,
      },
      // 权限前缀
      permissionPrefix: {
        type: String,
        required: true,
      },
      // 是否显示多选列
      showSelection: {
        type: Boolean,
        default: false,
      },
      // 是否显示序号列
      showIndex: {
        type: Boolean,
        default: false,
      },
      // 是否显示新增按钮
      showAdd: {
        type: Boolean,
        default: false,
      },

      // 是否显示操作列
      showOperation: {
        type: Boolean,
        default: true,
      },
      // 操作列宽度
      operationWidth: {
        type: String,
        default: "200",
      },
      // 是否显示分页
      showPagination: {
        type: Boolean,
        default: true,
      },

      // 是否显示导出按钮
      showExport: {
        type: Boolean,
        default: true,
      },
      // 是否使用自定义导出功能
      customExport: {
        type: Boolean,
        default: false,
      },
      // 是否显示关键字搜索
      showKeywordSearch: {
        type: Boolean,
        default: true,
      },
      // 是否显示默认日期范围搜索
      showDateRange: {
        type: Boolean,
        default: true,
      },
      // 导出Excel文件名
      exportFileName: {
        type: String,
        default: "导出数据",
      },
      // 初始搜索条件
      initSearchForm: {
        type: Object,
        default: () => ({}),
      },
      bt1Name: {
        type: String,
        default: "编辑",
      },
      bt2Name: {
        type: String,
        default: "删除",
      },
    },
    data() {
      return {

        tableLoading: false,
        tableData: [],
        searchForm: {
          keyword: "",
          dateRange: [],
          ...this.initSearchForm,
        },
        pagination: {
          currentPage: 1,
          pageSize: 10,
          total: 0,
        },
        multipleSelection: [], // 多选数据
        statusChangingRows: new Set(), // 正在改变状态的行ID
        originalStatusMap: new Map(), // 保存原始状态值
      };
    },

    computed: {
      ...mapGetters(["permission"]),
    },
    created() {
      this.getTableData();
    },
    methods: {
      displayEmpty(value) {
        return value === null || value === undefined || value === '' ? '-' : value;
      },
      // 检查权限
      hasPermission(permission) {
        return this.permission.includes(permission);
      },

      // 获取表格数据
      async getTableData() {
        this.tableLoading = true;
        try {
          const params = {
            ...this.searchForm,
            page: this.pagination.currentPage,
            limit: this.pagination.pageSize,
          };

          // 处理日期范围
          if (this.searchForm.dateRange && this.searchForm.dateRange.length === 2) {
            params.startTime = this.searchForm.dateRange[0];
            params.endTime = this.searchForm.dateRange[1];
            delete params.dateRange;
          }

          const res = await this.fetchData(params);
          this.tableData = res.list;
          this.pagination.total = res.total || 0;
          if (this.tableData.length > 0) {
            //console.log('第一条数据字段:', Object.keys(this.tableData[0]));
            //console.log('第一条完整数据:', JSON.parse(JSON.stringify(this.tableData[0])));

            // console.log("列定义", this.columns);
            // console.log("第一条数据", this.tableData[0]);
          }
        } catch (error) {
          console.error("获取表格数据失败:", error);
        } finally {
          this.tableLoading = false;
        }
      },

      handleAdd() {
        this.$emit('add');
      },

      // 搜索
      handleSearch() {
        this.pagination.currentPage = 1;
        this.getTableData(this.searchForm);
      },

      // 重置搜索
      resetSearch() {
        this.$refs.searchForm.resetFields();
        this.pagination.currentPage = 1;
        this.$emit("reset");
        this.getTableData();
      },
      getTagType(value, column) {
        if (!column?.tagConfig) return ''
        const strValue = String(value)
        return column.tagConfig[strValue]?.type || ''
      },
      shouldShowDash(value) {
        // 0 和 false 视为有效值，不显示 -
        return value === null ||
          value === undefined ||
          value === '' ||
          (Array.isArray(value) && value.length === 0) ||
          (typeof value === 'object' && Object.keys(value).length === 0);
      },
      getTagText(value, column) {
        // 1. 检查必要参数
        if (!column?.tagConfig) return value ?? '-'
        if (this.shouldShowDash(value)) return '-';
        // 2. 统一转为字符串比较（兼容数字/字符串值）
        const strValue = String(value)
        // 3. 优先从tagConfig获取
        if (column.tagConfig[strValue]?.text) {
          return column.tagConfig[strValue].text
        }
        // 4. 兜底显示原始值
        return strValue
      },

      // 分页大小改变
      handleSizeChange(val) {
        this.pagination.pageSize = val;
        this.getTableData();
      },

      // 当前页改变
      handleCurrentChange(val) {
        this.pagination.currentPage = val;
        this.getTableData();
      },

      // 多选
      handleSelectionChange(val) {
        this.multipleSelection = val;
        this.$emit("selection-change", val);
      },

      // 状态改变
      handleStatusChange(row) {
        // 保存原始状态值
        this.originalStatusMap.set(row.id, row.status === 1 ? 0 : 1);
        // 设置loading状态
        this.statusChangingRows.add(row.id);
        // 发射状态改变事件给父组件
        this.$emit("status-change", row, this.handleStatusChangeResult);
      },

      // 处理状态改变的结果（成功或失败）
      handleStatusChangeResult(row, success = true, errorMessage = '') {
        // 移除loading状态
        this.statusChangingRows.delete(row.id);
        
        if (success) {
          // 成功：清除原始状态记录
          this.originalStatusMap.delete(row.id);
        } else {
          // 失败：回滚到原始状态
          const originalStatus = this.originalStatusMap.get(row.id);
          if (originalStatus !== undefined) {
            // 找到表格数据中对应的行并回滚状态
            const targetRow = this.tableData.find(item => item.id === row.id);
            if (targetRow) {
              targetRow.status = originalStatus;
            }
            // 清除原始状态记录
            this.originalStatusMap.delete(row.id);
          }
          
          // 显示错误提示
          if (errorMessage) {
            this.$message.error(errorMessage);
          }
        }
      },

      // 编辑
      handleEdit(row) {
        this.$emit("edit", row);
      },

      // 删除
      handleDelete(row) {
        this.$confirm("确认删除该记录吗?", "提示", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          })
          .then(() => {
            this.$emit("delete", row);
          })
          .catch(() => {});
      },

      // 导出Excel
      handleExport() {
        if (this.customExport) {
          // 使用自定义导出
          this.$emit('custom-export');
        } else {
          // 默认Excel导出
          const tHeader = this.columns.map((item) => item.label);
          const filterVal = this.columns.map((item) => item.prop);
          const data = this.formatJson(filterVal, this.tableData);

          exportJsonToExcel(tHeader, data, this.exportFileName);
        }
      },

      // 处理导出数据
      formatJson(filterVal, jsonData) {
        return jsonData.map((v) =>
          filterVal.map((j) => {
            if (j === "status") {
              return v[j] === 1 ? "启用" : "禁用";
            }
            return v[j];
          })
        );
      },

      // 刷新表格
      refresh() {
        this.getTableData();
      },

      // 获取选中的行
      getSelection() {
        return this.multipleSelection;
      },
    },
  };
</script>

<style scoped>
  .universal-table-container {
    box-sizing: border-box;
    padding: 50px 30px;
    background: #fff;
  }

  .search-area {
    margin-bottom: 20px;
    display: flex;
    justify-content: space-between;
  }

  .pagination-area {
    margin-top: 20px;
    text-align: right;
  }

  .button-fix {
    padding: 0 20px;

  }
</style>
